package bigdata.service.impl;

import bigdata.dao.UserMapper;
import bigdata.pojo.User;
import bigdata.service.UserService;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.sql.DataSource;
import java.sql.Connection;
import java.util.List;

@CacheConfig(cacheNames="userCache")
//@Service("userService")
@Service(interfaceClass = UserService.class)
@Component
public class UserServiceImpl implements UserService {
	
	@Autowired
	CacheManager cacheManager;
	
	@Autowired
	private UserMapper userMapper;
	
	@CacheEvict(/*value="userCache", */key="#id")
	@Override
	public int delUser(Integer id) {
		/*
		int i = userMapper.deleteUserById(id);
		if(i>0) {
			//手写cache
			Cache cache = cacheManager.getCache("userCache");
			cache.evict(id);
		}
		return i;
		*/
		//
		return userMapper.deleteUserById(id);
	}
	
	@CacheEvict(/*value="userCache", */key="#user.id")
	@Override
	public int updateUser(User user) {
		/*
		//更新数据同时更新缓存
		int i = userMapper.modify(user);
		if(i>0) {
			//手写cache
			Cache cache = cacheManager.getCache("userCache");
			cache.put(user.getId(), user);
		}
		return i;
		*/
		// alt + /
		return userMapper.modify(user);
	}

	//方法4
	@Cacheable(/*value="userCache", */key="#id")
	@Override
	public User getUser(Integer id) {
		//手写cache
		//Cache cache = cacheManager.getCache("userCache");
		/*
		//方法1
		User user = null;
		ValueWrapper wrapper = cache.get(id);
		if(wrapper == null){
			user = userMapper.getUserById(id);
			cache.put(id, user);
		} else {
			user = (User) wrapper.get();
		}
		return user;
		//方法2 , Java 匿名内部类
		return cache.get(id, new Callable<User>(){
			@Override
			public User call() throws Exception {
				return userMapper.getUserById(id);
			}
		});
		*/
		//方法3 , Java8 lamba 表达式
		//return cache.get(id, ()-> userMapper.getUserById(id));
		//
		return userMapper.getUserById(id);
	}

	@Override
	public User getUser(String userCode) {
		//
		return userMapper.getUserByName(userCode);
	}
	
	@Override
	public List<User> getUserLists(User user) {
		//
		return userMapper.getUserLists(user);
	}

	@Override
	public int count() {
		return userMapper.count();
	}

	@Override
	public List<User> getUserList() {
		return userMapper.getUserList();
	}
	
	@Override
	public int add(User user) {
		return userMapper.add(user);
	}
	////////////////// 事务  //////////////////
	@Autowired
	DataSource dataSource;
	
	public int addUser(User user) throws Exception {
		Connection conn = null;
		try {
			conn = dataSource.getConnection();
			conn.setAutoCommit(false);//手动提交
			//省略数据库操作
			conn.commit();
		} catch (Exception e) {
			//回滚
			conn.rollback();
		} finally {
			conn.close();
		}
		return 0;
	}
	
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	/**
	 * service 存在的意义
	 * 1、一个服务接口同时调用多个 dao 接口，生成订单的服务接口（订单表、购物车、库存表、用户表）
	 * 2、不仅调用多个接口，更重要的是保持数据库中表数据的一致性（事务）
	 * @throws Exception 
	 */
	@Override
	@Transactional(rollbackFor=Exception.class)
	public int modify(User user) throws Exception {
		//订单表、订单名细、购物车表、库存表、出库记录表、满100减80、优惠券等调用省略
		//调用用户表
		int i = userMapper.modify(user);
		//最终支付出错
		if(i == 1) {//spring事务控制默认只识别运行时异常
			//throw new RuntimeException("支付出错");//继承自 Exception
			throw new Exception("清空购物车出错");
		}
		//物流相关
		//jdbcTemplate.execute(sql);
		//jdbcTemplate.query(sql, rowMapper);
		return i;
	}

}
